package Utility;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import Context.ContextHolder;
import Context.Context;

/**
 * @category Utility module
 * @author Sean Lionheart
 * @version 1.0.0.0
 * The log manager, via which the client can writer a log entry.
 */
public class LogManager {
	private ArrayList<ILogWriter> logWriter;
	private LogPolicy logPolicy;
	private static LogManager logManager = null;
	
	/**
	 * Get the single log manager.
	 * @return The log manager.
	 */
	public static LogManager getSingletonManager() {
		if(logManager == null) {
			logManager = new LogManager();
		}
		return logManager;
	}
	/**
	 * The constructor.
	 */
	public LogManager() {
		logPolicy = new LogPolicy();
		logWriter = new ArrayList<ILogWriter>();
		createWriter();
	}
	/**
	 * Write the log by the given message and category.
	 * @param logMessage The message of the log.
	 * @param logCategory The category of the log.
	 */
	public void writeLog(String logMessage, int logCategory) {
		LogEntry entry = new LogEntry(logMessage,logCategory);
		writeLog(entry);
	}
	/**
	 * Write the given log entry.
	 * @param entry The log entry to write.
	 */
	public void writeLog(LogEntry entry) {
		ArrayList<ILogFilter> allFilters = logPolicy.getFilters();
		for(ILogFilter filter : allFilters) {
			if(filter.filtrateLog(entry)) {
				for(ILogWriter writer: logWriter) {
					writer.writeLog(entry);
				}
			}
		}
	}
	public void writeInfoLog(String message) {
		writeLog(message, LogContext.LOG_INFO);
	}
	public void writeDebugLog(String message) {
		writeLog(message, LogContext.LOG_DEBUG);
	}
	public void writeExceptionLog(String message) {
		writeLog(message, LogContext.LOG_EXCEPTION);
	}
	public void writeWarning(String message) {
		writeLog(message, LogContext.LOG_WARNING);
	}
	/**
	 * Create the writer by the configuration.
	 */
	@SuppressWarnings("unchecked")
	private void createWriter() {
		
		Context ctx = ContextHolder.getContext();
		Properties allProperties = ctx.getAllProperties();
		
		Iterator it = allProperties.entrySet().iterator();
		while(it.hasNext()) {
			Map.Entry<String,String> entry= (Map.Entry<String,String>) it.next();
			String className = entry.getKey();
			String writerEnable = entry.getValue();
			
			if(className.startsWith(LogContext.LOGWRITER_PREFIX) 
					&& writerEnable.equals(LogContext.ENABLE)) {				
				try {
					Class<ILogWriter> writerClass =  
						(Class<ILogWriter>) Class.forName(className);
					ILogWriter writer = writerClass.newInstance();
					if(writer != null) {
						logWriter.add(writer);
					}
				}
				catch (ClassNotFoundException e) {
					// TODO: handle exception
					e.printStackTrace();
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
